/**
 * $version:  0.1 
 * $Date: 2012-04-21 
 *
 * Copyright (C) 2010-2011 Jawa Software. All rights reserved.
 *
 */

package org.jawa.menu;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.jawa.core.cache.Cache;
import org.jawa.core.cache.CacheFactory;
import org.jawa.core.database.DbConnectionManager;
import org.jawa.core.exception.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 菜单管理类.
 * @author Y-N
 *
 */
public class MenuManager {
	private static final Logger Log = LoggerFactory.getLogger(MenuManager.class);

	private static class MenuManagerContainer {
		private static MenuManager instance = new MenuManager();
	}

	/** 菜单缓存 */
	private Cache<Long, Menu> menuCache;

	private MenuManager() {
		// 初始化缓存.
		menuCache = CacheFactory.createCache("Menu");
	}

	/**
	 * 返回菜单管理的单一实例.
	 *
	 * @return a 菜单管理单一实例.
	 */
	public static MenuManager getInstance() {
		return MenuManagerContainer.instance;
	}

	/**
	 * 根据菜单ID 返回菜单.
	 *
	 * @param menuId 菜单ID.
	 * @return 菜单.
	 * @throws NotFoundException 菜单没有找到.
	 */
	public Menu getMenu(Long menuId) throws NotFoundException {
		if (menuId == null) {
			throw new NotFoundException("菜单ID 不可以为空");
		}
		Menu menu = menuCache.get(menuId);
		if (menu == null) {
			synchronized (menuId) {
				menu = menuCache.get(menuId);
				if (menu == null) {
					menu = loadMenu(menuId);
					menuCache.put(menuId, menu);
				}
			}
		}
		return menu;
	}

	private Menu loadMenu(Long menuId) throws NotFoundException {
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			con = DbConnectionManager.getConnection();
			pstmt = con
					.prepareStatement("SELECT menu_id,menu_name,menu_parent_id,menu_picture,menu_url,menu_sort,menu_click,menu_dbclick,module_detail,remark "
							+ " FROM app_menu WHERE 1=1 AND menu_id = ? ");
			pstmt.setLong(1, menuId);
			rs = pstmt.executeQuery();
			if (!rs.next()) {
				throw new NotFoundException();
			}
			Menu menu = new Menu();
			menu.setMenuId(rs.getLong("menu_id"));
			menu.setMenuName(rs.getString("menu_name"));
			menu.setMenuParentId(rs.getLong("menu_parent_id"));
			menu.setMenuPicture(rs.getString("menu_picture"));
			menu.setMenuUrl(rs.getString("menu_url"));
			menu.setMenuSort(rs.getLong("menu_sort"));
			menu.setMenuClick(rs.getString("menu_click"));
			menu.setMenuDbClick(rs.getString("menu_dbclick"));
			menu.setModuleDetail(rs.getString("module_detail"));
			menu.setRemark(rs.getString("remark"));
			return menu;
		} catch (Exception e) {
			Log.error("从数据库中获取菜单时发生错误! MENU_ID : " + Long.toString(menuId), e);
			throw new NotFoundException(e.getMessage());
		} finally {
			DbConnectionManager.closeConnection(rs, pstmt, con);
		}

	}

	/**
	 * 返回上级菜单下的所有直接子菜单
	 * @param parentId
	 * @return
	 */
	public List<Menu> getTopMenus() {
		List<Menu> childrenMenus = new ArrayList<Menu>(100);
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			con = DbConnectionManager.getConnection();
			pstmt = con
					.prepareStatement("SELECT menu_id  "
							+ " FROM app_menu a WHERE a.menu_parent_id IS NULL  ORDER BY menu_sort ASC  ");
			rs = pstmt.executeQuery();
			while (rs.next()) {
				long menuId = rs.getLong("menu_id");
				Menu menu;
				try {
					menu = getMenu(menuId);
					childrenMenus.add(menu);
				} catch (NotFoundException e) {
					//忽略
				}
			}
		} catch (SQLException e) {
			Log.error("查询下级菜单时发生错误!", e);
		} finally {
			DbConnectionManager.closeConnection(rs, pstmt, con);
		}
		return childrenMenus;

	}
	
	/**
	 * 返回上级菜单下的所有直接子菜单
	 * @param parentId
	 * @return
	 */
	public List<Menu> getChildrenMenus(Long parentId) {
		List<Menu> childrenMenus = new ArrayList<Menu>(500);
		Connection con = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			con = DbConnectionManager.getConnection();
			pstmt = con
					.prepareStatement("SELECT menu_id  "
							+ " FROM app_menu a WHERE 1=1 AND a.menu_parent_id = ?  ORDER BY menu_sort asc  ");
			pstmt.setLong(1, parentId);
			rs = pstmt.executeQuery();
			while (rs.next()) {
				long menuId = rs.getLong("menu_id");
				Menu menu;
				try {
					menu = getMenu(menuId);
					childrenMenus.add(menu);
				} catch (NotFoundException e) {
					//忽略
				}
			}
		} catch (SQLException e) {
			Log.error("查询下级菜单时发生错误!", e);
		} finally {
			DbConnectionManager.closeConnection(rs, pstmt, con);
		}
		return childrenMenus;

	}
}
